//
//  Maze24ModelTests.swift
//  Maze24ModelTests
//
//  Created by Mars on 2020/11/14.
//

import XCTest
@testable import Maze24

class Maze24ModelTests: XCTestCase {

  override func setUpWithError() throws {
    // Put setup code here. This method is called before the invocation of each test method in the class.
  }

  override func tearDownWithError() throws {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
  }
  
  func buildExpression() -> Tree {
    let root = Tree(node: .operator(.mul), left: nil, right: nil)
   
    var l = Tree(node: .operand(24), left: nil, right: nil)
    root.left = l
    
    var node = Tree(node: .operator(.sub), left: nil, right: nil)
    l = Tree(node: .operator(.div), left: nil, right: nil)
    var r = Tree(node: .operand(1), left: nil, right: nil)
    
    node.left = l
    node.right = r
    
    root.right = node
    
    l = Tree(node: .operand(18), left: nil, right: nil)
    r = Tree(node: .operand(9), left: nil, right: nil)
    
    node = node.left!
    node.left = l
    node.right = r
    
    return root
  }
  
  func testJudgeTarget() {
    let falseArray = [1, 1, 1, 1]
    XCTAssert(Model().judgeTarget(falseArray) == false)
    
    let trueArray = [18, 1, 9, 24]
    XCTAssert(Model().judgeTarget(trueArray))
  }
  
  func testTreeCalculation() throws {
    let root = buildExpression()
    XCTAssert(root.calculate() == 9, "The tree calculation doesn't work well.")
    
    /// - TODO: We could add mul and div expressions in this test.
  }
  
  func testExpression() {
    let root = buildExpression()
    XCTAssertEqual(root.expression(), "(24×((18÷9)-1))")
  }
  
  func testTreeBuild() {
    let tokens: [Token] = [
      .operand(2), .operator(.mul), .operand(13),
      .operand(15), .operator(.sub), .operand(2),
      .operand(1), .operator(.add), .operand(1)
    ]
    
    let tree = Tree(from: tokens)
    let expr = tree.expression()
    
    XCTAssert(expr == "((1+1)×(15-2))")
  }
  
  func testModelButtonUpdate() {
    let model = Model()
    model.update()
    
    XCTAssert(model.buttons.count == 4)
  }
}
